package com.aiyige.page.filter;

import android.app.Activity;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.aiyige.R;
import com.aiyige.arouter.Router;
import com.aiyige.arouter.config.ARouterConfig;
import com.aiyige.base.api.ApiManager;
import com.aiyige.base.api.ResponseCode;
import com.aiyige.model.Page;
import com.aiyige.model.moment.entity.Moment;
import com.aiyige.page.discovery.model.ActivityData;
import com.aiyige.page.discovery.model.ActivityResp;
import com.aiyige.page.filter.adapter.FilterAdapter;
import com.aiyige.page.filter.model.ActivityFilterInfoRequest;
import com.aiyige.page.filter.model.Filter;
import com.aiyige.page.filter.model.FilterInfo;
import com.aiyige.page.filter.model.FilterResponse;
import com.aiyige.page.filter.util.FilterUtil;
import com.aiyige.page.learn.adapter.LearnDataAdapter;
import com.aiyige.page.filter.adapter.OrderAdapter;
import com.aiyige.page.filter.model.Order;
import com.aiyige.page.webview.util.PreloadUtil;
import com.aiyige.utils.ErrorUtil;
import com.aiyige.utils.ListUtil;
import com.aiyige.utils.RetrofitUtil;
import com.aiyige.utils.SafeAsyncTask;
import com.aiyige.utils.StringUtils;
import com.aiyige.utils.ToastX;
import com.aiyige.utils.UIHelper;
import com.aiyige.utils.widget.ActivityDescriptionView;
import com.aiyige.utils.widget.AutoRefreshCommonDataView;
import com.aiyige.utils.widget.CommonDataView;
import com.alibaba.android.arouter.facade.annotation.Autowired;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.alibaba.fastjson.JSON;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.sothree.slidinguppanel.SlidingUpPanelLayout;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Response;

@Route(path = ARouterConfig.ActivityFilterPage)
public class ActivityFilterPage extends AppCompatActivity implements CommonDataView.RetrofitStub {
    @BindView(R.id.titleBackBtn)
    ImageView titleBackBtn;
    @BindView(R.id.titleTv)
    TextView titleTv;
    @BindView(R.id.orderTv)
    TextView orderTv;
    @BindView(R.id.orderArrowIv)
    ImageView orderArrowIv;
    @BindView(R.id.orderLayout)
    FrameLayout orderLayout;
    @BindView(R.id.dividerLine1)
    View dividerLine1;
    @BindView(R.id.filterTv)
    TextView filterTv;
    @BindView(R.id.filterLayout)
    FrameLayout filterLayout;
    @BindView(R.id.cdv)
    AutoRefreshCommonDataView cdv;
    @BindView(R.id.orderRv)
    RecyclerView orderRv;
    @BindView(R.id.dragView)
    LinearLayout dragView;
    @BindView(R.id.slidingLayout)
    SlidingUpPanelLayout slidingLayout;
    @Autowired
    ActivityData activityData = null;
    OrderAdapter orderAdapter;
    boolean orderViewVisibility;
    boolean filterViewVisibility;
    boolean shouldRefresh = false;
    Order order;
    List<Filter> filterList = new LinkedList<>();
    @BindView(R.id.orderLabelIv)
    ImageView orderLabelIv;

    @BindView(R.id.resetBtn)
    TextView resetBtn;
    @BindView(R.id.confirmBtn)
    TextView confirmBtn;
    @BindView(R.id.filterPanel)
    FrameLayout filterPanel;
    @BindView(R.id.drawerLayout)
    DrawerLayout drawerLayout;
    @BindView(R.id.errorLayout)
    View errorLayout;
    @BindView(R.id.loadingLayout)
    View loadingLayout;
    @BindView(R.id.filterIv)
    ImageView filterIv;
    @BindView(R.id.adv)
    ActivityDescriptionView adv;
    @BindView(R.id.filterRv)
    RecyclerView filterRv;
    FilterAdapter filterAdatper;
    boolean requestDataSucceed = false;
    LearnDataAdapter learnDataAdapter;
    boolean shouldHighLightFilterView = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.page_activity_filter);
        ButterKnife.bind(this);
        ARouter.getInstance().inject(this);
        if (activityData == null) {
            ToastX.show(R.string.unknown_error);
            finish();
            return;
        }
        init();
        doClickStatistics();
        configActivityTitleAndDescIfNeed();
    }

    public void configActivityTitleAndDescIfNeed() {
        if (TextUtils.isEmpty(activityData.getActivityTitle()) || TextUtils.isEmpty(activityData.getActivityDesc())) {
            new RequestActivityTitleDescTask(this).execute();
        }
    }


    public void doClickStatistics() {
        ApiManager.getService().activityZoneClickStatistics(activityData.getSourceId()).enqueue(ApiManager.NOOP_CALLBACK);
    }

    public void updateFilterViewHighLight() {
        if (shouldHighLightFilterView) {
            filterTv.setSelected(true);
            filterIv.setSelected(true);
        } else {
            filterTv.setSelected(false);
            filterIv.setSelected(false);
        }
    }

    public void init() {
        shouldRefresh = false;
        orderViewVisibility = false;
        filterViewVisibility = false;
        learnDataAdapter = new LearnDataAdapter();
        learnDataAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                Moment moment = learnDataAdapter.getItem(position);
                Router.start(moment.getRouter());
            }
        });
        cdv.config(learnDataAdapter, this);
        cdv.setCallback(new AutoRefreshCommonDataView.Callback() {
            @Override
            public void onClearRequestState() {
                if (shouldRefresh) {
                    cdv.refresh();
                }
            }
        });

        order = Order.newBuilder()
                .key(Order.GENERAL)
                .title(StringUtils.getString(R.string.general_order))
                .build();
        drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
        drawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
            @Override
            public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {

            }

            @Override
            public void onDrawerOpened(@NonNull View drawerView) {
                filterViewVisibility = true;
                drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
            }

            @Override
            public void onDrawerClosed(@NonNull View drawerView) {
                filterViewVisibility = false;
                drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
            }

            @Override
            public void onDrawerStateChanged(int newState) {

            }
        });
        orderAdapter = new OrderAdapter();
        orderRv.setLayoutManager(new LinearLayoutManager(this));
        orderAdapter.bindToRecyclerView(orderRv);
        orderAdapter.setNewData(Arrays.asList(
                Order.newBuilder().key(Order.GENERAL).selected(true).title(StringUtils.getString(R.string.general_order)).build(),
                Order.newBuilder().key(Order.SALES_VOLUME_DESC).selected(false).title(StringUtils.getString(R.string.sales_volume_desc_order)).build(),
                Order.newBuilder().key(Order.VIEW_COUNT_DESC).selected(false).title(StringUtils.getString(R.string.view_count_desc_order)).build(),
                Order.newBuilder().key(Order.PRICE_DESC).selected(false).title(StringUtils.getString(R.string.price_desc_order)).build(),
                Order.newBuilder().key(Order.PRICE_ASC).selected(false).title(StringUtils.getString(R.string.price_asc_order)).build(),
                Order.newBuilder().key(Order.PUBLISH_TIME_DESC).selected(false).title(StringUtils.getString(R.string.publish_time_desc_order)).build()));

        orderAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                order = orderAdapter.getItem(position);
                for (int i = 0; i < orderAdapter.getData().size(); ++i) {
                    orderAdapter.getData().get(i).setSelected(i == position);
                }
                orderAdapter.notifyDataSetChanged();
                orderViewVisibility = false;
                updateOrderViewVisibility();
                updateOrderViewText();
                shouldRefresh = true;
                cdv.refresh();
            }
        });
        slidingLayout.setFadeOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                orderViewVisibility = false;
                updateOrderViewVisibility();
            }
        });
        filterRv.setLayoutManager(new LinearLayoutManager(this));
        filterRv.addItemDecoration(new RecyclerView.ItemDecoration() {
            @Override
            public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
                super.getItemOffsets(outRect, view, parent, state);
                int index = parent.getChildAdapterPosition(view);
                if (index == parent.getAdapter().getItemCount() - 1) {
                    outRect.set(0, 0, 0, UIHelper.dip2px(15));
                }
            }
        });
        filterAdatper = new FilterAdapter(this);
        filterAdatper.bindToRecyclerView(filterRv);
        updateOrderViewText();
        updateFilterViewHighLight();
        new RequestDataTask(this).execute();
        cdv.doRefreshRequest();

        //持续高亮排序选项
        orderLabelIv.setSelected(true);
        orderTv.setSelected(true);
        orderArrowIv.setSelected(true);

        adv.setTitle(StringUtils.getString(R.string.activity_description));
        adv.setContent(activityData.getActivityDesc());
        titleTv.setText(activityData.getActivityTitle());
    }


    public void updateOrderViewText() {
        orderTv.setText(order.getTitle());
    }

    public void updateOrderViewVisibility() {
        if (orderViewVisibility) {
            orderLabelIv.setSelected(true);
            orderTv.setSelected(true);
            orderArrowIv.setSelected(true);
            orderArrowIv.animate()
                    .rotation(180)
                    .start();
        } else {
            orderLabelIv.setSelected(true);
            orderTv.setSelected(true);
            orderArrowIv.setSelected(true);
            orderArrowIv.animate()
                    .rotation(0)
                    .start();
        }
        slidingLayout.setPanelState(orderViewVisibility ? SlidingUpPanelLayout.PanelState.EXPANDED : SlidingUpPanelLayout.PanelState.COLLAPSED);
    }

    public void updateFilterViewVisibility() {
        if (filterViewVisibility) {
            drawerLayout.openDrawer(Gravity.END);
        } else {
            drawerLayout.closeDrawer(Gravity.END);
        }
    }

    public void doResetFilter() {
        if (!ListUtil.isEmpty(filterList)) {
            filterList.clear();
            shouldRefresh = true;
            cdv.refresh();
            shouldHighLightFilterView = checkUseFilter();
            updateFilterViewHighLight();
        }
    }

    public void doConfirmFilter() {
        List<Filter> stageFilterList = FilterUtil.extractActiveFilter(filterAdatper.getData());
        if (!FilterUtil.safeEquals(filterList, stageFilterList)) {
            filterList.clear();
            filterList.addAll(stageFilterList);
            shouldRefresh = true;
            cdv.refresh();
            shouldHighLightFilterView = checkUseFilter();
            updateFilterViewHighLight();
        }
    }

    @OnClick({R.id.errorLayout, R.id.titleBackBtn, R.id.orderLayout, R.id.filterLayout, R.id.resetBtn, R.id.confirmBtn})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.errorLayout:
                new RequestDataTask(this).execute();
                break;
            case R.id.resetBtn: {
                filterViewVisibility = false;
                updateFilterViewVisibility();
                doResetFilter();
                break;
            }
            case R.id.confirmBtn: {
                filterViewVisibility = false;
                updateFilterViewVisibility();
                doConfirmFilter();
                break;
            }
            case R.id.titleBackBtn: {
                finish();
                break;
            }
            case R.id.orderLayout: {
                if (!requestDataSucceed) break;
                orderViewVisibility = !orderViewVisibility;
                updateOrderViewVisibility();
                break;
            }
            case R.id.filterLayout: {
                if (!requestDataSucceed) break;
                orderViewVisibility = false;
                updateOrderViewVisibility();
                filterViewVisibility = !filterViewVisibility;
                if (filterViewVisibility) {
                    prepareFilterView();
                }
                updateFilterViewVisibility();
                break;
            }
        }
    }

    public void prepareFilterView() {
        FilterUtil.prepare(filterAdatper.getData(), filterList);
        filterAdatper.notifyDataSetChanged();
    }


    public boolean checkUseFilter() {
        if (!ListUtil.isEmpty(filterList)) return true;
        return false;
    }

    public void showLoadingLayout() {
        errorLayout.setVisibility(View.INVISIBLE);
        loadingLayout.setVisibility(View.VISIBLE);
    }


    public void showErrorLayout() {
        errorLayout.setVisibility(View.VISIBLE);
        loadingLayout.setVisibility(View.INVISIBLE);
    }

    public void hideCoverLayout() {
        errorLayout.setVisibility(View.INVISIBLE);
        loadingLayout.setVisibility(View.INVISIBLE);
    }

    @Override
    public Call<ResponseBody> call(long currentPage) {
        shouldRefresh = false;
        Call<ResponseBody> call = ApiManager.getService().filterActivity(order.getKey(), ActivityFilterInfoRequest.newBuilder()
                .sourceId(activityData.getSourceId())
                .filterInfo(FilterInfo.parse(filterList))
                .build(), currentPage, 15);
        return call;
    }

    @Override
    public CommonDataView.HandleResult handleResponse(String respJson, List resultList) {
        try {
            Page page = JSON.parseObject(respJson, Page.class);
            List<Moment> momentList = new LinkedList<>();
            if (!TextUtils.isEmpty(page.getContent())) {
                momentList.addAll(JSON.parseArray(page.getContent(), Moment.class));
            }
            for (Moment moment : momentList) {
                Moment safeMoment = new Moment(moment);
                resultList.add(safeMoment);
                PreloadUtil.preloadH5Moment(safeMoment);
            }
            return new CommonDataView.HandleResult(page.isLast());
        } catch (Exception e) {
            return new CommonDataView.HandleResult(e.getMessage());
        }
    }

    public class RequestDataTask extends SafeAsyncTask<Object, Object, Object> {
        List<Filter> totalFilterList = new LinkedList<>();

        public RequestDataTask(Activity activity) {
            super(activity);
            showLoadingLayout();
        }

        @Override
        public void safeOnPostExecute(Object o) {
            if (o instanceof Exception) {
                ToastX.show((Exception) o);
                showErrorLayout();
            } else {
                requestDataSucceed = true;
                hideCoverLayout();
                filterAdatper.setNewData(totalFilterList);
            }
        }

        @Override
        protected Object doInBackground(Object... objects) {
            try {
                Response<ResponseBody> response = ApiManager.getService().getActivityFilter(activityData.getSourceId()).execute();
                if (response.code() != ResponseCode.OK) {
                    throw new Exception(ErrorUtil.extractMessageFromErrorResponse(response));
                }
                String json = RetrofitUtil.getResponseBodyAsString(response);
                List<FilterResponse> filterResponseList = JSON.parseArray(json, FilterResponse.class);
                totalFilterList.addAll(FilterUtil.parse(filterResponseList));
                return null;
            } catch (Exception e) {
                return e;
            }
        }

    }

    class RequestActivityTitleDescTask extends SafeAsyncTask<Object, Object, Object> {
        ActivityResp activityResp;

        public RequestActivityTitleDescTask(Activity activity) {
            super(activity);
        }

        @Override
        public void safeOnPostExecute(Object o) {
            if (o instanceof Exception) {

            } else {
                activityData.setActivityTitle(activityResp.getName());
                activityData.setActivityDesc(activityResp.getRemark());
                activityData.setCoverUrl(activityResp.getCover());
                titleTv.setText(activityData.getActivityTitle());
                adv.setContent(activityData.getActivityDesc());
            }
        }

        @Override
        protected Object doInBackground(Object... objects) {
            try {
                Response<ResponseBody> response = ApiManager.getService().getActivityEntryById(activityData.getSourceId()).execute();
                if (response.code() != ResponseCode.OK) {
                    throw new Exception(ErrorUtil.extractMessageFromErrorResponse(response));
                }
                String json = RetrofitUtil.getResponseBodyAsString(response);
                activityResp = JSON.parseObject(json, ActivityResp.class);
                if (activityResp == null) {
                    throw new Exception(StringUtils.getString(R.string.unknown_error));
                }
                return null;
            } catch (Exception e) {
                return e;
            }
        }
    }

}
